G_DEFINE_TYPE (GdkWin32CairoContext, gdk_win32_cairo_context, GDK_TYPE_CAIRO_CONTEXT)
-static cairo_surface_t *
-create_cairo_surface_for_layered_window (GdkWin32Surface *impl,
- int width,
- int height,
- int scale)
-{
- if (width > impl->dib_width ||
- height > impl->dib_height)
- {
- cairo_surface_t *new_cache;
-
- impl->dib_width = MAX (impl->dib_width, MAX (width, 1));
- impl->dib_height = MAX (impl->dib_height, MAX (height, 1));
- /* Create larger cache surface, copy old cache surface over it */
- new_cache = cairo_win32_surface_create_with_dib (CAIRO_FORMAT_ARGB32,
- impl->dib_width,
- impl->dib_height);
-
- if (impl->cache_surface)
- {
- cairo_t *cr = cairo_create (new_cache);
- cairo_set_source_surface (cr, impl->cache_surface, 0, 0);
- cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
- cairo_paint (cr);
- cairo_destroy (cr);
- cairo_surface_flush (new_cache);
-
- cairo_surface_destroy (impl->cache_surface);
- }
-
- impl->cache_surface = new_cache;
-
- cairo_surface_set_device_scale (impl->cache_surface,
- scale,
- scale);
- }
-
- return cairo_surface_reference (impl->cache_surface);
-}
-
static cairo_surface_t *
create_cairo_surface_for_surface (GdkSurface *surface,
int scale)
width = MAX (width, 1);
height = MAX (height, 1);
- if (self->layered)
- self->window_surface = create_cairo_surface_for_layered_window (impl, width, height, scale);
- else
- self->window_surface = create_cairo_surface_for_surface (surface, scale);
+ self->window_surface = create_cairo_surface_for_surface (surface, scale);
- if (self->layered ||
- !self->double_buffered)
- {
- /* Layered windows paint on the window_surface (which is itself
- * an in-memory cache that the window maintains, since layered windows
- * do not support incremental redraws.
- * Non-double-buffered windows paint on the window surface directly
- * as well.
- */
- self->paint_surface = cairo_surface_reference (self->window_surface);
- }
+ if (!self->double_buffered)
+ /* Non-double-buffered windows paint on the window surface directly */
+ self->paint_surface = cairo_surface_reference (self->window_surface);
else
{
if (width > self->db_width ||
}
/* Clear the paint region.
- * For non-double-buffered and for layered rendering we must
- * clear it, otherwise semi-transparent pixels will "add up"
- * with each repaint.
- * For double-buffered rendering we must clear the old pixels
- * from the DB cache surface that we're going to use as a buffer.
+ * For non-double-buffered rendering we must clear it, otherwise
+ * semi-transparent pixels will "add up" with each repaint.
+ * We must also clear the old pixels from the DB cache surface
+ * that we're going to use as a buffer.
*/
cr = cairo_create (self->paint_surface);
cairo_set_source_rgba (cr, 0, 0, 0, 00);
* to be here.
*/
- /* Layered windows have their own, special copying section
- * further down. For double-buffered windows we need to blit
+ /* For double-buffered windows we need to blit
* the DB buffer contents into the window itself.
*/
- if (!self->layered &&
- self->double_buffered)
+ if (self->double_buffered)
{
cairo_t *cr;
cairo_surface_flush (self->window_surface);
- /* Update layered window, updating its contents, size and position
- * in one call.
- */
- if (self->layered)
- {
- RECT client_rect;
-
- /* Get the position/size of the window that GDK wants. */
- _gdk_win32_get_window_client_area_rect (surface, scale, &client_rect);
- _gdk_win32_update_layered_window_from_cache (surface, &client_rect, TRUE, TRUE, TRUE);
- }
-
g_clear_pointer (&self->paint_surface, cairo_surface_destroy);
g_clear_pointer (&self->window_surface, cairo_surface_destroy);
}
gboolean
_gdk_win32_surface_enable_transparency (GdkSurface *window)
{
- GdkWin32Surface *impl;
DWM_BLURBEHIND blur_behind;
HRGN empty_region;
HRESULT call_result;
if (window == NULL || GDK_SURFACE_HWND (window) == NULL)
return FALSE;
- impl = GDK_WIN32_SURFACE (window);
-
- /* layered windows don't need blurbehind for transparency */
- if (impl->layered)
- return TRUE;
-
if (!gdk_display_is_composited (gdk_surface_get_display (window)))
return FALSE;
surface->width = width;
surface->height = height;
- impl->layered = FALSE;
- impl->layered_opacity = 1.0;
-
impl->surface_scale = _gdk_win32_display_get_monitor_scale_factor (display_win32, NULL, NULL, NULL);
impl->unscaled_width = width * impl->surface_scale;
impl->unscaled_height = height * impl->surface_scale;
* Returns TRUE if window has no decorations.
* Usually it means CSD windows, because GTK
* calls gdk_surface_set_decorations (window, 0);
- * This is used to decide whether a toplevel should
- * be made layered, thus it
- * only returns TRUE for toplevels (until GTK minimal
- * system requirements are lifted to Windows 8 or newer,
- * because only toplevels can be layered).
*/
gboolean
_gdk_win32_surface_lacks_wm_decorations (GdkSurface *window)
new_exstyle &= ~WS_EX_TOOLWINDOW;
}
- /* We can get away with using layered windows
- * only when no decorations are needed. It can mean
- * CSD or borderless non-CSD windows (tooltips?).
- *
- * If this window cannot use layered windows, disable it always.
- * This currently applies to windows using OpenGL, which
- * does not work with layered windows.
- */
- if (impl->suppress_layered == 0)
- {
- if (_gdk_win32_surface_lacks_wm_decorations (window))
- impl->layered = g_strcmp0 (g_getenv ("GDK_WIN32_LAYERED"), "0") != 0;
- }
- else
- impl->layered = FALSE;
-
- if (impl->layered)
- new_exstyle |= WS_EX_LAYERED;
- else
- new_exstyle &= ~WS_EX_LAYERED;
-
if (get_effective_window_decorations (window, &decorations))
{
all = (decorations & GDK_DECOR_ALL);
window_size->cy = window_rect->bottom - window_rect->top;
}
-void
-_gdk_win32_update_layered_window_from_cache (GdkSurface *surface,
- RECT *client_rect,
- gboolean do_move,
- gboolean do_resize,
- gboolean do_paint)
-{
- POINT window_position;
- SIZE window_size;
- BLENDFUNCTION blender;
- HDC hdc;
- SIZE *window_size_ptr;
- POINT source_point = { 0, 0 };
- POINT *source_point_ptr;
- GdkWin32Surface *impl = GDK_WIN32_SURFACE (surface);
-
- gdk_win32_get_window_size_and_position_from_client_rect (surface,
- client_rect,
- &window_size,
- &window_position);
-
- blender.BlendOp = AC_SRC_OVER;
- blender.BlendFlags = 0;
- blender.AlphaFormat = AC_SRC_ALPHA;
- blender.SourceConstantAlpha = impl->layered_opacity * 255;
-
- /* Strictly speaking, we don't need to supply hdc, source_point and
- * window_size to just move the window. However, without these arguments
- * the window moves but does not update its contents on Windows 7 when
- * desktop composition is off. This forces us to provide hdc and
- * source_point. window_size is here to avoid the function
- * inexplicably failing with error 317.
- */
- hdc = cairo_win32_surface_get_dc (impl->cache_surface);
- window_size_ptr = &window_size;
- source_point_ptr = &source_point;
-
- if (gdk_display_is_composited (gdk_surface_get_display (surface)))
- {
- if (!do_paint)
- hdc = NULL;
- if (!do_resize)
- window_size_ptr = NULL;
- if (!do_move)
- source_point_ptr = NULL;
- }
-
- /* Don't use UpdateLayeredWindow on minimized windows */
- if (IsIconic (GDK_SURFACE_HWND (surface)))
- API_CALL (SetWindowPos, (GDK_SURFACE_HWND (surface),
- SWP_NOZORDER_SPECIFIED,
- window_position.x, window_position.y,
- window_size.cx, window_size.cy,
- SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOREDRAW));
- else
- API_CALL (UpdateLayeredWindow, (GDK_SURFACE_HWND (surface), NULL,
- &window_position, window_size_ptr,
- hdc, source_point_ptr,
- 0, &blender, ULW_ALPHA));
-}
-
void
gdk_win32_surface_do_move_resize_drag (GdkSurface *window,
int x,
(rect.left != new_rect.left ||
rect.top != new_rect.top))
{
+ SIZE window_size;
+ POINT window_position;
+
context->native_move_resize_pending = FALSE;
gdk_surface_request_layout (window);
- if (impl->layered)
- {
- _gdk_win32_update_layered_window_from_cache (window, &new_rect, TRUE, FALSE, FALSE);
- }
- else
- {
- SIZE window_size;
- POINT window_position;
-
- gdk_win32_get_window_size_and_position_from_client_rect (window,
- &new_rect,
- &window_size,
- &window_position);
-
- API_CALL (SetWindowPos, (GDK_SURFACE_HWND (window),
- SWP_NOZORDER_SPECIFIED,
- window_position.x, window_position.y,
- 0, 0,
- SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOSIZE));
- }
+ gdk_win32_get_window_size_and_position_from_client_rect (window,
+ &new_rect,
+ &window_size,
+ &window_position);
+
+ API_CALL (SetWindowPos, (GDK_SURFACE_HWND (window),
+ SWP_NOZORDER_SPECIFIED,
+ window_position.x, window_position.y,
+ 0, 0,
+ SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOSIZE));
}
if (context->op == GDK_WIN32_DRAGOP_RESIZE ||
return (GdkSurface*) gdk_win32_handle_table_lookup (anid);
}
-void
-gdk_win32_surface_set_opacity (GdkSurface *window,
- double opacity)
-{
- LONG exstyle;
- typedef BOOL (WINAPI *PFN_SetLayeredWindowAttributes) (HWND, COLORREF, BYTE, DWORD);
- PFN_SetLayeredWindowAttributes setLayeredWindowAttributes = NULL;
- GdkWin32Surface *impl;
-
- g_return_if_fail (GDK_IS_SURFACE (window));
-
- if (GDK_SURFACE_DESTROYED (window))
- return;
-
- if (opacity < 0)
- opacity = 0;
- else if (opacity > 1)
- opacity = 1;
-
- impl = GDK_WIN32_SURFACE (window);
-
- if (impl->layered)
- {
- if (impl->layered_opacity != opacity)
- {
- RECT window_rect;
-
- impl->layered_opacity = opacity;
-
- _gdk_win32_get_window_client_area_rect (window, impl->surface_scale, &window_rect);
- _gdk_win32_update_layered_window_from_cache (window, &window_rect, TRUE, TRUE, TRUE);
- }
-
- return;
- }
-
- exstyle = GetWindowLong (GDK_SURFACE_HWND (window), GWL_EXSTYLE);
-
- if (!(exstyle & WS_EX_LAYERED))
- SetWindowLong (GDK_SURFACE_HWND (window),
- GWL_EXSTYLE,
- exstyle | WS_EX_LAYERED);
-
- setLayeredWindowAttributes =
- (PFN_SetLayeredWindowAttributes)GetProcAddress (GetModuleHandle ("user32.dll"), "SetLayeredWindowAttributes");
-
- if (setLayeredWindowAttributes)
- {
- API_CALL (setLayeredWindowAttributes, (GDK_SURFACE_HWND (window),
- 0,
- opacity * 0xff,
- LWA_ALPHA));
- }
-}
-
gboolean
gdk_win32_surface_is_win32 (GdkSurface *window)
{
if (IsWindowVisible (hwnd))
break;
- if ((WS_EX_LAYERED & GetWindowLongPtr (hwnd, GWL_EXSTYLE)) != WS_EX_LAYERED)
- break;
-
/* Window was hidden, will be shown. Erase it, GDK will repaint soon,
* but not soon enough, so it's possible to see old content before
* the next redraw, unless we erase the window first.
RECT
gdk_win32_surface_handle_queued_move_resize (GdkDrawContext *draw_context)
{
- GdkWin32CairoContext *cairo_ctx = NULL;
GdkSurface *surface;
GdkWin32Surface *impl;
int scale;
impl = GDK_WIN32_SURFACE (surface);
scale = gdk_surface_get_scale_factor (surface);
- if (GDK_IS_WIN32_CAIRO_CONTEXT (draw_context))
- {
- cairo_ctx = GDK_WIN32_CAIRO_CONTEXT (draw_context);
- cairo_ctx->layered = impl->layered;
- }
-
gdk_win32_surface_get_queued_window_rect (surface, scale, &queued_window_rect);
- /* Apply queued resizes for non-double-buffered and non-layered windows
+ /* Apply queued resizes for non-double-buffered windows
* before painting them (we paint on the window DC directly,
* it must have the right size).
* Due to some poorly-undetstood issue delayed
* resizing of double-buffered windows can produce weird
* artefacts, so these are also resized before we paint.
*/
- if (impl->drag_move_resize_context.native_move_resize_pending &&
- (cairo_ctx == NULL || !cairo_ctx->layered))
+ if (impl->drag_move_resize_context.native_move_resize_pending)
{
impl->drag_move_resize_context.native_move_resize_pending = FALSE;
gdk_win32_surface_apply_queued_move_resize (surface, queued_window_rect);